package org.zh.client.config;

import org.zh.client.jdbc.TCCache;
import org.zh.client.jdbc.Table;
import org.zh.client.tra_aop.SQLiteJDBC;
import org.zh.util.ComponentScan;

import javax.sql.DataSource;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.InetAddress;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;


/**
 * 初始化是相对于spring 来说的   before() 在spring初始化之前  进行需要的全局系统变量的初始化System.setProperty（）
 * after()  在spring初始化完之后   主要是一些其他的需要spring资源的  初始化
 */
public class ZHOpenInit {
    public static final String serverPort = "app.server.port";
    public static final String serverContextPath = "app.server.context-path";
    public static final String appName = "app.application.name";
    public static final String appVersion = "app.application.version";
    public static final String appIpAddress = "app.local.ipAddress";
    public static final String httpBasePath = "app.http.basePath";
    public static final String zhOpenClientTaskDelay = "zhOpen.clientTask.delay";
    public static final String zhOpenClientTaskPeriod = "zhOpen.clientTask.period";
    public static final String zhOpenTransactionTaskKeepTime = "zhOpen.transactionTask.keepTime";
    public static final String zhOpenTransactionTaskDelay = "zhOpen.transactionTask.delay";
    public static final String zhOpenTransactionTaskPeriod = "zhOpen.transactionTask.period";
    public static final String zhOpenLogEnv = "zhOpen.logEnv";
    public static final String zhOpenLogName = "zhOpen.logName";
    public static final String zhOpenRCBaseUrl = "zhOpen.rcBaseUrl";

    public static void before() {
        Properties env = new Properties();
        try {
            env.load(ZHOpenInit.class.getClassLoader().getResourceAsStream("application.properties"));
            System.setProperty(serverPort, env.getProperty("server.port"));
            System.setProperty(serverContextPath, env.getProperty("server.servlet.context-path"));
            System.setProperty(appName, env.getProperty("spring.application.name"));
            System.setProperty(appVersion, env.getProperty("spring.application.version"));
            System.setProperty(appIpAddress, InetAddress.getLocalHost().getHostAddress());
            System.setProperty(httpBasePath, "http://" + System.getProperty(appIpAddress) + ":" + env.getProperty("server.port", "8080") + env.getProperty("server.servlet.context-path", ""));
            System.setProperty(zhOpenClientTaskDelay, env.getProperty("zhOpen.clientTask.delay", "10000"));
            System.setProperty(zhOpenClientTaskPeriod, env.getProperty("zhOpen.clientTask.period", "50000"));
            System.setProperty(zhOpenTransactionTaskKeepTime, env.getProperty("zhOpen.transactionTask.keepTime", "60000"));
            System.setProperty(zhOpenTransactionTaskDelay, env.getProperty("zhOpen.transactionTask.delay", "60000"));
            System.setProperty(zhOpenTransactionTaskPeriod, env.getProperty("zhOpen.transactionTask.period", "60000"));
            System.setProperty(zhOpenLogEnv, env.getProperty("zhOpen.logEnv", "dev"));
            System.setProperty(zhOpenLogName, env.getProperty("zhOpen.logName", "app.%u.%g.log"));
            System.setProperty(zhOpenRCBaseUrl, env.getProperty("zhOpen.rcBaseUrl", "http://localhost:8848"));
            SQLiteJDBC.initTable();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    public static void after(Class<?> application) {
        //宕机  数据检测恢复  运行
        DataSource dataSource = SpringContextUtil.getBean(DataSource.class);
        List<Class<?>> classes;
        try {
            classes = ComponentScan.run(application);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        classes.stream().filter(clazz -> Arrays.stream(clazz.getAnnotations()).map(Annotation::annotationType).toList().contains(Table.class)).forEach(clazz -> {
            Table annotation = clazz.getAnnotation(Table.class);
            try {
                TCCache.initCache(dataSource.getConnection(), annotation.value(), clazz);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        });
        SQLiteJDBC.initData();

    }


}
